from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from model import Game, PlayerInfo, Player
from serialization import *
from utils import *
import simplejson
import urllib

class CreateGameHandler(webapp.RequestHandler):
    def post(self):
        jsonGame = urllib.unquote(self.request.get('game')).decode('utf8')
        jsonPlayerInfo = urllib.unquote(self.request.get('player_info')).decode('utf8')

        rawGame = simplejson.loads(jsonGame)
        rawPlayerInfo = simplejson.loads(jsonPlayerInfo)

        playerInfo = PlayerInfo(name = rawPlayerInfo['name'])
        playerInfo.put()

        player = Player(
            info = playerInfo,
            isReady = False
        )
        player.put()

        game = Game(
            name = rawGame['name'],
#            password = rawGame['password'],
            playerKeys = [player.key()]
        )
        game.put()

        self.response.out.write('{ ' +
                                '"game_id": "' + str(game.key().id()) + '",' +
                                '"player_id": "' + str(player.key().id()) + '"' +
                                '}')

class ListGamesHandler(webapp.RequestHandler):
    def get(self):
        games = Game.all()
        dicGames = games_to_dic(games)
        jsonGames = simplejson.dumps(dicGames)
        self.response.out.write(jsonGames)

class JoinGameHandler(webapp.RequestHandler):
    def post(self):
        gameId = long(self.request.get('game_id'))
        game = Game.get_by_id(gameId)

        jsonPlayerInfo = urllib.unquote(self.request.get('player_info')).decode('utf8')
        rawPlayerInfo = simplejson.loads(jsonPlayerInfo)
        playerInfo = PlayerInfo(name = rawPlayerInfo['name'])
        playerInfo.put()

        player = Player(info = playerInfo)
        player.put()

        game.playerKeys.append(player.key())
        game.put()

        self.response.out.write('{"player_id": "' + str(player.key().id()) + '"}')

class UpdatePlayerInfoHandler(webapp.RequestHandler):
    def post(self):
        playerId = int(self.request.get('player_id'))
        jsonPlayerInfo = urllib.unquote(self.request.get('player_info')).decode('utf8')
        rawPlayerInfo = simplejson.loads(jsonPlayerInfo)

        player = Player.get_by_id(playerId)
        playerInfo = player.info
        playerInfo.role = rawPlayerInfo['role']
        playerInfo.put()

        self.response.out.write('OK')

class SetIsPlayerReadyInfoHandler(webapp.RequestHandler):
    def get(self):
        playerId = long(self.request.get('player_id'))
        player = Player.get_by_id(playerId)

        isReady = bool(self.request.get('is_ready'))
        player.isReady = isReady
        player.put()

        self.response.out.write('OK')

class GetGameHandler(webapp.RequestHandler):
    def get(self):
        gameId = long(self.request.get('game_id'))
        game = Game.get_by_id(gameId)
        jsonGame = simplejson.dumps(game_to_dic(game))
        self.response.out.write(jsonGame)

class UpdateLocationHandler(webapp.RequestHandler):
    def get(self):
        playerId = long(self.request.get('player_id'))
        player = Player.get_by_id(playerId)

        latitude = float(self.request.get('latitude'))
        longitude = float(self.request.get('longitude'))

        player.latitude = latitude
        player.longitude = longitude
        player.put()

        self.response.out.write('Location updated')

class GetGameStateHandler(webapp.RequestHandler):
    def get(self):
        gameId = long(self.request.get("game_id"))
        game = Game.get_by_id(gameId)

        playerId = long(self.request.get("player_id"))
        requestingPlayer = Player.get_by_id(playerId)

        gameState = {'game_objects': []}

        for player in game.players():
            if player.key().id() == requestingPlayer.key().id():
                continue

            x, y = calcVectorInMetersBetweenTwoGeoCoords(
                    requestingPlayer.latitude,
                    requestingPlayer.longitude,
                    player.latitude,
                    player.longitude
            )

            nX, nY = vector2dNormalize(x, y)
            distance = vector2dLength(x, y)

            gameObject = {
                'player': player_info_to_dic(player.info),
                'direction_x': nX,
                'direction_y': nY,
                'distance_in_meters': distance
            }

            gameState['game_objects'].append(gameObject)

        self.response.out.write(simplejson.dumps(gameState))

def main():
  app = webapp.WSGIApplication(
      [
          ('/game/create', CreateGameHandler),
          ('/game/list', ListGamesHandler),
          ('/game/join', JoinGameHandler),
          ('/game/player/info/update', UpdatePlayerInfoHandler),
          ('/game/player/set_is_ready', SetIsPlayerReadyInfoHandler),
          ('/game/get', GetGameHandler),
          ('/location/update', UpdateLocationHandler),
          ('/game/state/get', GetGameStateHandler)
      ],
      debug=True
  )

  run_wsgi_app(app)

if __name__ == '__main__':
  main()
